package com.towexin.application.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.towexin.config.file.NonStaticResourceHttpRequestHandler;
import com.towexin.application.system.domain.FileUpload;
import com.towexin.application.system.mapper.FileUploadMapper;
import com.towexin.application.system.service.FileUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * TODO
 *
 * @author Towexin
 * @version 1.0
 * @date 2021/4/27 11:47
 */
@Service
public class FileUploadServiceImpl extends ServiceImpl<FileUploadMapper, FileUpload> implements FileUploadService {
	@Autowired
	private NonStaticResourceHttpRequestHandler nonStaticResourceHttpRequestHandler;

	@Override
	public String saveFile(MultipartFile file) {
		FileUpload fileUpload = new FileUpload();

		try {
			String localPath = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath().replace("target\\classes",
																										   "file\\");
			String type = Objects.requireNonNull(file.getOriginalFilename())
					.split("\\.")[file.getOriginalFilename().split("\\.").length - 1];

			String mon = (Calendar.getInstance().get(Calendar.MONTH) + 1) < 10
					? "0" + (Calendar.getInstance().get(Calendar.MONTH) + 1)
					: "" + (Calendar.getInstance().get(Calendar.MONTH) + 1);

			String path = type + "\\" + Calendar.getInstance().get(Calendar.YEAR) + "\\" + mon + "\\";

			fileUpload.setFileName(file.getOriginalFilename().replace("." + type, ""));
			fileUpload.setFileType(type);
			fileUpload.setFileSize(file.getSize());
			fileUpload.setFilePath(path + file.getOriginalFilename());
			fileUpload.setContentType(file.getContentType());
			// fileUpload.setUploadUser(SecurityUtils.getSubject().getPrincipal().toString());

			File checkPath = new File(localPath + path);
			if (!checkPath.isDirectory()) {
				checkPath.mkdirs();
			}

			File localFile = new File(localPath + path, file.getOriginalFilename());
			if (localFile.exists()) {
				String fileName = UUID.randomUUID() + file.getOriginalFilename();
				File newFile = new File(localPath + path, fileName);
				file.transferTo(newFile);
				fileUpload.setFileName(fileName);
				fileUpload.setFilePath(path + fileName);
			} else {
				file.transferTo(localFile);
			}

		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		return save(fileUpload) ? fileUpload.getId() : null;
	}

	@Override
	public void getFile(String id, HttpServletResponse response, HttpServletRequest request) throws Exception {
		FileUpload fileUpload = getOne(new QueryWrapper<FileUpload>()
				.select("file_name", "file_type", "file_path", "content_type", "file_size").eq("id", id));

		if (fileUpload != null) {
			String localPath = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath().replace("target\\classes",
																										   "file\\");
			Path path = Paths.get(localPath + fileUpload.getFilePath());
			if (Files.exists(path)) {
				response.setContentType(fileUpload.getContentType());

				request.setAttribute(NonStaticResourceHttpRequestHandler.ATTR_FILE, path);

				//// response的响应的编码方式为utf-8
				// response.setCharacterEncoding("utf-8");
				// 设置大小
				response.setContentLengthLong(fileUpload.getFileSize());
				//// 设置文件名
				// response.setHeader("Content-Disposition",
				//// "attachment;filename="+fileUpload.getFileName()+"."+fileUpload.getFileType());

				nonStaticResourceHttpRequestHandler.handleRequest(request, response);
			} else {
				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
				response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
			}
		}
	}

	@Override
	public void getImgFile(String id, HttpServletResponse response, HttpServletRequest request) throws Exception {
		FileUpload fileUpload = getOne(new QueryWrapper<FileUpload>()
											   .select("file_name", "file_type", "file_path", "content_type", "file_size").eq("id", id));

		if (fileUpload != null && fileUpload.getContentType().contains("image")) {
			String localPath = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath().replace("target\\classes",
																										   "file\\");
			Path path = Paths.get(localPath + fileUpload.getFilePath());
			if (Files.exists(path)) {
				response.setContentType(fileUpload.getContentType());
				request.setAttribute(NonStaticResourceHttpRequestHandler.ATTR_FILE, path);
				response.setContentLengthLong(fileUpload.getFileSize());
				nonStaticResourceHttpRequestHandler.handleRequest(request, response);
			} else {
				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
				response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
			}
		}
	}

	@Override
	public void downloadFile(String id, HttpServletResponse response, HttpServletRequest request) throws Exception {
		FileUpload fileUpload = getOne(new QueryWrapper<FileUpload>()
				.select("file_name", "file_type", "file_path", "content_type", "file_size").eq("id", id));

		if (fileUpload != null) {
			String localPath = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath().replace("target\\classes",
																										   "file\\");
			Path path = Paths.get(localPath + fileUpload.getFilePath());
			if (Files.exists(path)) {
				response.setContentType(fileUpload.getContentType());
				request.setAttribute(NonStaticResourceHttpRequestHandler.ATTR_FILE, path);

				// response的响应的编码方式为utf-8
				response.setCharacterEncoding("utf-8");
				// 设置大小
				response.setContentLengthLong(fileUpload.getFileSize());
				// 设置文件名
				response.setHeader("Content-Disposition",
						"attachment;filename=" + fileUpload.getFileName() + "." + fileUpload.getFileType());

				try {
					nonStaticResourceHttpRequestHandler.handleRequest(request, response);
				} catch (ServletException | IOException e) {
					e.printStackTrace();
				}
			} else {
				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
				response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
			}
		}
	}

	@Override
	public boolean deleteFile(List<String> ids) {
		List<FileUpload> fileUploads = list(
				new QueryWrapper<FileUpload>().select("file_path", "file_name", "file_type").in("id", ids));
		for (FileUpload fileUpload : fileUploads) {
			File file = new File(fileUpload.getFilePath());
			if (file.exists()) {
				file.delete();
			}
		}
		return removeByIds(ids);
	}
}
